package cn.edu.hit.graphdata;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.Serializable;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by Wang on 2018/12/5.
 */
public class FaultPortMapping {
    private static FaultPortMapping ourInstance;

    public static FaultPortMapping getInstance() {
        if (ourInstance == null) {
            synchronized (FaultPortMapping.class) {
                if (ourInstance == null) {
                    ourInstance = new FaultPortMapping();
                }
            }
        }
        return ourInstance;
    }

    private FaultPortMapping() {
    }

    private Map<String, FPMapping> fpMapping = new HashMap<>();

    public static class FPMapping implements Serializable {
        public String faultId;
        public Set<String> portIds;
        public Integer showType;
        public boolean isOpen;
    }

    public void addMapping(String faultId, List<String> portIds) {
        FPMapping mapping;
        if (fpMapping.containsKey(faultId)) {
            mapping = fpMapping.get(faultId);
        } else {
            mapping = new FPMapping();
            mapping.faultId = faultId;
            mapping.portIds = new HashSet<>();
        }
        mapping.portIds.addAll(portIds);
        fpMapping.put(faultId, mapping);
    }

    public Map<String, FPMapping> getFpMapping() {
        return fpMapping;
    }

    public void setShowType(String faultId, int showType) {
        FPMapping mapping;
        if (fpMapping.containsKey(faultId)) {
            mapping = fpMapping.get(faultId);
        } else {
            mapping = new FPMapping();
            mapping.faultId = faultId;
            mapping.portIds = new HashSet<>();
        }
        mapping.showType = showType;
        fpMapping.put(faultId, mapping);
    }

    public String exportAsJson() throws JsonProcessingException {
        return mapper.writeValueAsString(fpMapping.values());
    }

    ObjectMapper mapper = new ObjectMapper();

    public void loadFromJson(String json) throws IOException {
        JavaType type = mapper.getTypeFactory().constructCollectionType(List.class, FPMapping.class);
        List<FPMapping> loaded = mapper.readValue(json, type);
        loaded.forEach(mp -> this.fpMapping.put(mp.faultId, mp));
    }

    public static void main(String[] args) throws IOException {
        FaultPortMapping mapping = FaultPortMapping.getInstance();
        String inputData = Files.lines(Paths.get("./fp-mapping.json")).reduce((a, b) -> a + b).get();
        mapping.loadFromJson(inputData);

        mapping.fpMapping.forEach((key, val) -> {
            val.isOpen = val.portIds != null && val.portIds.size() > 0;
        });

        String result = mapping.exportAsJson();
        BufferedWriter writer = Files.newBufferedWriter(Paths.get("./fp-mapping.json"),
                StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
        writer.append(result);
        writer.flush();
        writer.close();
    }

    private static List<String> box(String[] list) {
        return Arrays.stream(list).collect(Collectors.toList());
    }

}
